stream的min,max,findFirst,findAny操作,我们先看下函数的定义
Optional<T> min(Comparator<? super T> comparator);
Optional<T> max(Comparator<? super T> comparator);
Optional<T> findFirst();
Optional<T> findAny();
这4个函数,都是返回的Optional对象,关于这个对象,如果有不清楚的,后期我们会做详细的介绍,现在只需要知道,这个类是对null做处理的,就可以了;
通过函数的定义,我们其实,已经可以看到,这4个函数的作用了,min和max传入的是一个Comparator这个是一个对比接口,那么返回就是根据比较的结果,取到的集合里面,最大的值,和最小的值;
findFirst和findAny,通过名字,就可以看到,对这个集合的流,做一系列的中间操作后,可以调用findFirst,返回集合的第一个对象,findAny返回这个集合中,取到的任何一个对象;通过这样的描述,我们也可以知道,在串行的流中,findAny和findFirst返回的,都是第一个对象;而在并行的流中,findAny返回的是最快处理完的那个线程的数据,所以说,在并行操作中,对数据没有顺序上的要求,那么findAny的效率会比findFirst要快的;下面,我们通过案例,介绍这几个的用法;
List<String> strs = Arrays.asList("d", "b", "a", "c", "a");
Optional<String> min = strs.stream().min(Comparator.comparing(Function.identity()));
Optional<String> max = strs.stream().max((o1, o2) -> o1.compareTo(o2));
System.out.println(String.format("min:%s; max:%s", min.get(), max.get()));// min:a; max:d
Optional<String> aa = strs.stream().filter(str -> !str.equals("a")).findFirst();
Optional<String> bb = strs.stream().filter(str -> !str.equals("a")).findAny();
Optional<String> aa1 = strs.parallelStream().filter(str -> !str.equals("a")).findFirst();
Optional<String> bb1 = strs.parallelStream().filter(str -> !str.equals("a")).findAny();
System.out.println(aa.get() + "===" + bb.get());// d===d
System.out.println(aa1.get() + "===" + bb1.get());// d===b or d===c
可以看到在min和max中,两种不同的写法,Function.identity(),表示当前对象String本身,如果集合里,是其他的实体类对象,那么可以根据实体类对象里的具体成员进行对象
后面的findFirst和findAny也都在串行和并行中,都有解释;最后Optional的get方法,是取到这个对象,这里的是String,取出来的就是字符串
public static void main(String[] args) {
int i = 0;
List<TimeTest> timeList = new ArrayList<>();
while (++i <= 5) {
TimeTest time = new TimeTest();
time.setTime(DateUtils.addMonths(DateUtils.now(), i));
timeList.add(time);
}
//插入一个空值
TimeTest time = new TimeTest();
timeList.add(time);
System.out.println("---------------初始值------------------");
timeList.forEach(o -> {
System.out.println(DateUtils.formatDateYMDHMS(o.getTime()));
});
System.out.println("---------------------------------------");
//下面有两种写法 推荐使用方法一
//代码解释: 将timeList流首先过滤时间不为空的,将需要比较的值转出map然后去重,最后取出最大值/最小值
//方法一 min(DateUtils::compareDate) 这种写法需要自己写工具类,且compareDate必须是static修饰
Date min = timeList.stream().filter(o -> o.getTime() != null).map(TimeTest::getTime).distinct().min(DateUtils::compareDate).get();
//方法二 max((e1, e2) -> e1.compareTo(e2))这种写法需要类里面含有比较方法
Date max = timeList.stream().filter(o -> o.getTime() != null).map(TimeTest::getTime).distinct().max((e1, e2) -> e1.compareTo(e2)).get();
System.out.println("min=" + DateUtils.formatDateYMDHMS(min));
System.out.println("max=" + DateUtils.formatDateYMDHMS(max));
}